package com.alibaba.cirtus.ots.application.app.ability.facade.v2serviceimpl;

import com.alibaba.citrus.ots.common.annotation.FacadeInvoker;
import com.alibaba.citrus.ots.sales.plan.model.SalesPlanReportAuditStatusEnum;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.cz.base.tool.result.Result;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.epoch.app.bcorder.model.dto.*;
import com.epoch.app.bcorder.service.BcOrderService;
import com.epoch.app.bcorder.service.SalesPlanService;
import com.epoch.app.otsapplicationappsdk.monthplancustomerlist.dto.AsnycRequest;
import com.epoch.app.otsapplicationappsdk.monthplancustomerlist.dto.RenderRequest;
import com.epoch.app.otsapplicationappsdk.monthplancustomerlist.dto.SubmitRequest;
import com.epoch.app.otsapplicationappsdk.monthplancustomerlist.service.MonthPlanCustomerListService;
import com.epoch.app.crplatformenhance.enums.RoleCodeEnum;
import com.google.common.collect.Lists;
import lombok.Data;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class MonthPlanCustomerV2ListServiceImpl implements MonthPlanCustomerListService {
    private static final Log log = Log.getLogger(MonthPlanCustomerV2ListServiceImpl.class);

    public static final int DEFAULT_PAGE_SIZE = 100;

    private static final String PLAN_ID = "planId";
    private static final String CURRENT_PAGE = "currentPage";
    private static final String PAGE_SIZE = "pageSize";
    private static final String FETCH_URL = "/api/bc_ots/page_query_customer_address_sales_plan_line_filter";


    @Autowired
    private SalesPlanService salesPlanService;

//    @Autowired
//    private BcOtsService bcOtsService;
    @Autowired
    private BcOrderService bcOtsService;

    @Override
    @FacadeInvoker
    public Object render(RenderRequest renderRequest) {
        JSONObject result = new JSONObject();
        try {
            if (renderRequest.getRequestBody() == null) {
                log.error("MonthPlanCustomerListServiceImpl.render 缺失必要参数");
                throw new Exception("缺失必要参数");
            }
            JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(renderRequest.getRequestBody()));
            String planId = jsonObject.getString(PLAN_ID);
            if (StringUtils.isBlank(planId)) {
                log.error("MonthPlanCustomerListServiceImpl.render 缺失必要参数{}", "planId");
                throw new Exception("缺失必要参数:planId");
            }
            Integer currentPage = jsonObject.getInteger(CURRENT_PAGE) == null ? 1 : jsonObject.getInteger(CURRENT_PAGE);
            Integer pageSize = jsonObject.getInteger(PAGE_SIZE) == null ? 10 : jsonObject.getInteger(PAGE_SIZE);
            handle(result, planId, currentPage, pageSize, null);
            result.put("success", true);
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", e.getMessage());
            log.error("MonthPlanCustomerListServiceImpl.render error:", e);
        }
        log.info(JSON.toJSONString(result));
        return result;
    }

    private void handle(JSONObject result, String planId, Integer currentPage, Integer pageSize, String value) throws Exception {
        result.put("editable", isEditable(planId));
        result.put(PLAN_ID, planId);
        result.put("fetchUrl", FETCH_URL);
        result.put("value", value);
        PageQueryPlanCustomerList2Request itemParam = new PageQueryPlanCustomerList2Request();
        itemParam.setPlanId(planId);
        itemParam.setPage(currentPage);
        itemParam.setSize(pageSize);
        if (StringUtils.isNotEmpty(value)) {
            itemParam.setCustomerName(value);
        }
        QuerySalePlanInfoRequest planParam = new QuerySalePlanInfoRequest();
        planParam.setId(planId);
        QuerySalePlanInfoResponse planInfoResponse = salesPlanService.querySalePlanInfo(planParam);
        Integer auditStatus = null;
        if (planInfoResponse != null && planInfoResponse.getResult() != null) {
            result.put("status", planInfoResponse.getResult().getStatus());
            result.put("auditStatus", auditStatus = planInfoResponse.getResult().getAuditStatus());
            String planNotice = planInfoResponse.getResult().getPlanNotice();
            if (StringUtils.isNotBlank(planNotice)) {
                result.put("planNotice", planNotice);
            }
            String formatPlanTime = planInfoResponse.getResult().getFormatPlanTime();
            if (StringUtils.isNotBlank(formatPlanTime)) {
                result.put("planTitle", formatPlanTime + "-月度计划");
            }
        }

        //查询月度计划明细 - 取月度计划明细id 提报区分是否小程序提报
        try {
            List<String> salesPlanDetailList  = new ArrayList<>();
            PageQuerySalesPlanLineList2Request pageQuerySalesPlanLineList2Request = new PageQuerySalesPlanLineList2Request();
            pageQuerySalesPlanLineList2Request.setPlanId(planId);
            PageQuerySalesPlanLineList2Response pageQuerySalesPlanLineList2Response = salesPlanService.pageQuerySalesPlanLineList2(pageQuerySalesPlanLineList2Request);
            if (Objects.nonNull(pageQuerySalesPlanLineList2Response)) {
                if (CollectionUtils.isNotEmpty(pageQuerySalesPlanLineList2Response.getResult())) {
                    for (SalesPlanLineSDO2 salesPlanLineSDO2 : pageQuerySalesPlanLineList2Response.getResult()) {
                        salesPlanDetailList.add(String.valueOf(salesPlanLineSDO2.getId()));
                    }
                }
                result.put("salesPlanDetailList",salesPlanDetailList);
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("C端查询月度计划明细异常pageQuerySalesPlanLineList2 " + e.getMessage());
        }
        PageQueryPlanCustomerList2Response itemResult = salesPlanService.pageQueryPlanCustomerList2(itemParam);
        if (itemResult == null) {
            throw new Exception("查询月度计划客户地址异常");
        }
        Integer total = itemResult.getTotal() == null ? 0 : itemResult.getTotal();
        List<SalesPlanStatCustomerSDO> itemResultResult = itemResult.getResult();
        JSONObject page = new JSONObject();
        page.put(CURRENT_PAGE, currentPage);
        page.put(PAGE_SIZE, pageSize);
        int totalPage = total / pageSize;
        if (total % pageSize > 0) {
            totalPage++;
        }
        page.put("totalPage", totalPage);
        result.put("page", page);
        if (!CollectionUtils.isEmpty(itemResultResult)) {
            List<JSONObject> itemList = Lists.newArrayList();
            for (SalesPlanStatCustomerSDO itemSDO : itemResultResult) {
                String addressCode = itemSDO.getCustomerAddress();
                String addressName = itemSDO.getCustomerAddressName();
                String customerName = itemSDO.getCustomerName();
                String manageEmployeeName = itemSDO.getManageEmployeeName();
                String customerAddressId = itemSDO.getCustomerAddressId();
                JSONObject item = new JSONObject();
                item.put("address", addressName);
                item.put("customerName", customerName);
                item.put("id", customerAddressId);
                item.put("addressCode", addressCode);
                boolean finishStatus = getFinishStatus(planId, addressCode);
                item.put("status", finishStatus ? "已完成" : "未完成");
                item.put("manageEmployeeName", manageEmployeeName);
                itemList.add(item);
            }
            result.put("items", itemList);
        }
        //是否可提交审核
        boolean disabled = true;
        if (auditStatus != null && (SalesPlanReportAuditStatusEnum.TO_BE_REVIEW.getCode() == auditStatus
                || SalesPlanReportAuditStatusEnum.REVIEW_REJECTED.getCode() == auditStatus)) {
            EmployeeGetCurrentLoginResponse currentLoginResponse = bcOtsService.employeeGetCurrentLogin();
            String roleCodes = currentLoginResponse.getRoleCodes();
            if (StringUtils.isNotBlank(roleCodes)
                    && (roleCodes.contains(RoleCodeEnum.SALE_MAN.getCode())
                    /*|| roleCodes.contains(RoleCodeEnum.DEPARTMENT_MANAGER.getCode())*/)) {
                disabled = !getFinishStatus(planId, null);
            } else {
                QueryPreSalesPlanReportAuditStatusRequest request = QueryPreSalesPlanReportAuditStatusRequest
                        .builder().planId(planId).modelId(planId).model(1).build();
                QueryPreSalesPlanReportAuditStatusResponse auditStatusResponse = salesPlanService.queryPreSalesPlanReportAuditStatus(request);
                disabled = auditStatusResponse == null || !auditStatusResponse.getResult();
            }
        }
        result.put("disable", disabled);
    }

    private Boolean getFinishStatus(String planId, String addressCode) {
        try {
            QueryCompletePercentSalesPlanLineResponse response = salesPlanService
                    .queryCompletePercentSalesPlanLine(QueryCompletePercentSalesPlanLineRequest.builder()
                            .planId(planId).customerAddress(addressCode).build());
            if (response != null && response.getResult() != null) {
                return response.getResult().doubleValue() == 100;
            }
        } catch (Exception e) {
            log.error("查询月度计划明细完成度异常", e);
        }
        return false;
    }


    @Override
    @FacadeInvoker
    public Object asnyc(AsnycRequest asnycRequest) {
        Object requestBody = asnycRequest.getRequestBody();
        if (requestBody == null) {
            return null;
        }
        JSONObject result = new JSONObject();
        try {
            JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(requestBody));
            JSONObject fields = jsonObject.getJSONObject("fields");
            Boolean close = fields.getBoolean("close");
            String value = fields.getString("value");
            JSONObject page = fields.getJSONObject("page");
            int pageSize = 10;
            int currentPage = 1;
            if (page != null) {
                pageSize = page.getInteger(PAGE_SIZE) == null ? 10 : page.getInteger(PAGE_SIZE);
                currentPage = page.getInteger(CURRENT_PAGE) != null ? page.getInteger(CURRENT_PAGE) : 1;
            }
            String planId = fields.getString(PLAN_ID);
            if (StringUtils.isBlank(planId)) {
                throw new Exception("缺失必要参数:planId");
            }
            if (fields.getBooleanValue("delete")) {
                JSONArray dataSource = fields.getJSONArray("dataSource");
                List<String> planLineIdList = getDelPlanLineIdList(dataSource, planId);
                if (!CollectionUtils.isEmpty(planLineIdList)) {
                    DeleteSalesPlanLineResponse deleteSalesPlanLineResponse = batchDelPlanLineByIdList(planLineIdList);
                    if (deleteSalesPlanLineResponse != null) {
                        if (deleteSalesPlanLineResponse.getSuccess()) {
                            currentPage = 1;
                            result.put("message", "删除成功");

                            //计划汇总
                            try {
                                PlanStatServiceRequest planStatServiceRequest = PlanStatServiceRequest.builder().planId(planId).build();
                                PlanStatServiceResponse planStatServiceResponse = salesPlanService.planStatService(planStatServiceRequest);
                                log.info("小程序月度计划删除客户后汇总更新操作结果" + JSONObject.toJSONString(planStatServiceResponse));
                            } catch (Exception e) {
                                log.error("小程序月度计划删除客户后汇总更新操作异常" + e.getMessage());
                            }
                            Thread.sleep(1000);
                        } else {
                            return Result.failure(null, deleteSalesPlanLineResponse.getMessage());
                        }
                    } else {
                        return Result.failure(null, "删除失败");
                    }
                } else {
                    return Result.failure(null, "未选择客户地址");
                }
            }
            if (close != null) {
                result.put("close", close);
            }
            handle(result, planId, currentPage, pageSize, value);
            result.put("success", true);
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", e.getMessage());
            log.error("MonthPlanCustomerListServiceImpl.render async:", e);
        }
        return result;
    }

    @Override
    @FacadeInvoker
    public Object submit(SubmitRequest submitRequest) {
        Object requestBody = submitRequest.getRequestBody();
        if (requestBody == null) {
            return null;
        }
        JSONObject result = new JSONObject();
        try {
            JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(requestBody));
            JSONObject fields = jsonObject.getJSONObject("fields");
            if (fields == null) {
                return null;
            }
            String planId = fields.getString(PLAN_ID);
            List<String> salesPlanDetailIdList = new ArrayList<>();
            if (fields.get("salesPlanDetailIdList") != null) {
                if (CollectionUtils.isNotEmpty(fields.getJSONArray("salesPlanDetailIdList"))) {
                    for (Object obj : fields.getJSONArray("salesPlanDetailIdList")) {
                        salesPlanDetailIdList.add(obj.toString());
                    }
                }
            }
            if (StringUtils.isBlank(planId)) {
                return null;
            }
            boolean submit = fields.getBooleanValue("submit");
            //提交审核
            if (submit) {
                ReportRequest reportRequest = ReportRequest.builder()
                        .model(1).planId(planId).modelId(planId).appletSubmission(true).salesPlanDetailIdList(salesPlanDetailIdList).build();
                ReportResponse reportResponse = salesPlanService.report(reportRequest);
                if (reportResponse != null) {
                    if (reportResponse.getSuccess()) {
                        handle(result, planId, 1, 10, null);
                        result.put("message", "提交成功");
                        result.put("success", true);
                    } else {
                        return Result.failure(null, reportResponse.getMessage());
                    }
                } else {
                    return Result.failure(null, "提交失败");
                }
            }
        } catch (Exception e) {
            log.error("打印异常",e);
            String errorMsg = StringUtils.isNotBlank(e.getMessage())
                    ? e.getMessage().contains("提报单中有尚未审核的审核单")
                    ? "提报单中有尚未审核的审核单，请先处理" : e.getMessage() : "系统异常";
            result.put("success", false);
            result.put("message", errorMsg);
        }
        return result;
    }

    private DeleteSalesPlanLineResponse batchDelPlanLineByIdList(List<String> planLineIdList) {
        DeleteSalesPlanLineRequest request = new DeleteSalesPlanLineRequest();
        List<JSONObject> list = planLineIdList.stream().map(id -> {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("id", id);
            return jsonObject;
        }).collect(Collectors.toList());
        request.setSalesPlanLineSDOList(list);
        log.info("批量删除月度计划详情request:{}", JSON.toJSONString(request));
        DeleteSalesPlanLineResponse response = salesPlanService.deleteSalesPlanLine(request);
        log.info("批量删除月度计划详情response:{}", JSON.toJSONString(response));
        return response;
    }

    private List<String> getDelPlanLineIdList(JSONArray dataSource, String planId) {
        List<String> planLineIdList = Lists.newArrayList();
        for (Object o : dataSource) {
            JSONObject item = JSONObject.parseObject(JSON.toJSONString(o));
            Boolean checked = item.getBoolean("checked");
            String addressId = item.getString("id");
            String addressCode = item.getString("addressCode");
            if (checked != null && checked && addressId != null) {
                PageQuerySalesPlanLineList2Request planLineListRequest = new PageQuerySalesPlanLineList2Request();
                planLineListRequest.setPage(1);
                planLineListRequest.setSize(DEFAULT_PAGE_SIZE);
                planLineListRequest.setPlanId(planId);
                planLineListRequest.setCustomerAddressId(addressId);
                planLineListRequest.setCustomerAddress(addressCode);
                PageQuerySalesPlanLineList2Response listResponse = salesPlanService.pageQuerySalesPlanLineList2(planLineListRequest);
                List<Object> planLineList = Lists.newArrayList();
                if (listResponse != null && listResponse.getSuccess() && !CollectionUtils.isEmpty(listResponse.getResult())) {
                    planLineList.addAll(listResponse.getResult());
                    if (listResponse.getTotal() > DEFAULT_PAGE_SIZE) {
                        int totalPage = listResponse.getTotal() / DEFAULT_PAGE_SIZE;
                        if (listResponse.getTotal() % DEFAULT_PAGE_SIZE > 0) {
                            totalPage++;
                        }
                        for (int i = 2; i <= totalPage; i++) {
                            planLineListRequest.setPage(i);
                            planLineListRequest.setSize(DEFAULT_PAGE_SIZE);
                            PageQuerySalesPlanLineList2Response pageResponse = salesPlanService.pageQuerySalesPlanLineList2(planLineListRequest);
                            if (listResponse.getSuccess()) {
                                planLineList.addAll(pageResponse.getResult());
                            }
                        }
                    }
                }
                if (!CollectionUtils.isEmpty(planLineList)) {
                    planLineList.forEach(
                            planLineObj -> planLineIdList.add(JSONObject.parseObject(JSON.toJSONString(planLineObj)).getLong("id").toString())
                    );
                }
            }
        }
        return planLineIdList;
    }

    private boolean isEditable(String planId) {
        PageQuerySalePlanListRequest request = new PageQuerySalePlanListRequest();
        request.setStart(0);
        request.setLimit(10);
        request.setId(planId);
        PageQuerySalePlanListResponse response = salesPlanService.pageQuerySalePlanList(request);
        if (response != null && response.getSuccess() && !CollectionUtils.isEmpty(response.getResult())) {
            SalesPlanSDO salesPlanSDO = JSONObject.parseObject(JSON.toJSONString(response.getResult().get(0)), SalesPlanSDO.class);
            Integer status = salesPlanSDO.getStatus();
            Integer auditStatus = salesPlanSDO.getAuditStatus();
            return (status != null && status <= 3) &&
                    (auditStatus == null || !(SalesPlanReportAuditStatusEnum.UNDER_REVIEW.getCode() == auditStatus
                            || SalesPlanReportAuditStatusEnum.APPROVED.getCode() == auditStatus));
        }
        return false;
    }

    @Data
    public static class Permission {
        private String id;
        private String code;
        private String name;
    }
}
